﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Globalization;
using devtm.Configuration;
using devtm.Editor.Configuration.formWpf;
using devtm.Helpers;
using devtm.Configuration.Models;
using devtm.Types.LazyLoading;
using devtm.Config;


namespace devtm.Editor.Configuration.Data
{
    public class TemplateType : ConfigProperty
    {

        //System.Text.RegularExpressions.Regex Reg = new System.Text.RegularExpressions.Regex(@"(,\sVersion=[\d.]*|,\sCulture=[\w]*|,\sPublicKeyToken=[\d\w]*|,\s[\w\d.]*)");


        public TemplateType() { }

        public TemplateType(PropertyInfo propertyinfo, ElementSection instance)
            : base(propertyinfo, instance)
        {
            var j = BoxSetting.GetBoxSetting(propertyinfo, ConfigConstants.Parametre.Key).FirstOrDefault();

            if (j != null)
            {
                if (j.Value is string)
                    using (ResolveWorker i = new ResolveWorker(Datas.Lazy.Resolver))
                    {
                        IsolateType = Type.GetType(j.ValueString);
                    }
                else if (j.Value is Type)
                    IsolateType = j.Value as Type;

            }
            else
                if (Editor != null)
                    IsolateType = (Editor as CustomDesignerTypeAttribute).Filter;

            // on a un attribut Required 
            if (Value != null)
                devtm.Configuration.Models.RequireConfigurationSectionAttribute.IsPresent(Value);






        }


        public Type IsolateType { get; set; }
        

        /// <summary>
        /// Runs the editor.
        /// </summary>
        public override void RunEditor()
        {

            if (IsolateType != null)
            {
                var dir = new FileInfo(IsolateType.Module.FullyQualifiedName).Directory;
                if (!Datas.DirectoriesSearch.ContainsKey(dir.FullName))
                    Datas.AddDirectoryLibrary(dir);
            }

            Datas.LoadTypes(Datas.DirectoriesSearch);

            SelectAssembly frm = new SelectAssembly(Datas.DirectoriesSearch, new TypeContraint(IsolateType));


            frm.ShowDialog();
            if (!String.IsNullOrEmpty(frm.Retour))

                if (base.Type == typeof(Type))
                    Value = frm.TypeRetour;
                else
                    Value = frm.Retour;
        }

        public override void Selector() { }



        public new virtual Object Value
        {
            get
            {
                return base.Value;
            }
            set
            {
                base.Value = value;
                devtm.Configuration.Models.RequireConfigurationSectionAttribute.IsPresent(value);
            }
        }


        protected override void ValueHasChanged()
        {
            base.ValueHasChanged();
            MyPropertyChanged("LiteDisplay");
        }

        public string LiteDisplay
        {
            get
            {

                var i = base.Value;
                if (i == null)
                    return String.Empty;

                if (i is Type)
                    return GetString((Type)i);
                else
                {
                    return GetString(Type.GetType((string)i));
                }
                    

                //return Reg.Replace(base.ValueString, "");
            }
        }

        private string GetString(Type type)
        {
            if (type == null)
                return string.Empty;

            String s = string.Empty;

            var p = type.GetGenericArguments();
            if (p.Length > 0)
            {
                s += type.Name.Substring(0, type.Name.Length - 2);
               
                s += "<";

                foreach (Type t in p)
                    s += GetString(t) + ", ";
                
                s = s.Substring(0, s.Length - 2);
                s += ">";

                foreach (Type t in p)
                    s += GetWhere(t);

            }
            else
            {

                if (type.IsGenericParameter)
                    s += type.Name;
                else
                    s += type.Name;

            }
            return s;
        }

        private string GetWhere(Type t)
        {

            string s = string.Empty;
            if (t.IsGenericParameter)
                foreach (var item in t.GetGenericParameterConstraints())
                    s = ", " + s + item.FullName;



            if (!string.IsNullOrEmpty(s))
                s = @" where " + t.Name + " : " + s.Substring(2);

            return s;
        }

    }

}



